﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Elements
{
    /// <summary>
    /// 形状基类
    /// </summary>
    public abstract class ShapeBaseV4
    {        
        /// <summary>
        /// 连接点
        /// </summary>
        public enum ShapeLinkPoints
        {
            左,
            上,
            右,
            下,
        }
        /// <summary>
        /// 形状ID
        /// </summary>
        public string Id { get; set; }
        /// <summary>
        /// 形状位置和尺寸
        /// </summary>
        public Rectangle Rect { get; set; }
        /// <summary>
        /// 背景颜色
        /// </summary>
        public Color BackgroundColor { get; set; }
        /// <summary>
        /// 形状内的文本
        /// </summary>
        public string Text { get; set; }
        /// <summary>
        /// 文本字体
        /// </summary>
        public Font TextFont { get; set; }
        /// <summary>
        /// 文本颜色
        /// </summary>
        public Color FontColor { get; set; }

        /// <summary>
        /// 绘制形状
        /// </summary>
        /// <param name="g"></param>
        public abstract void Draw(Graphics g);

        /// <summary>
        /// 获取连接点坐标
        /// </summary>
        /// <param name="linkPoint"></param>
        /// <returns></returns>
        public virtual Point GetLinkPoint(ShapeLinkPoints linkPoint)
        {
            //默认实现以矩形为基础，取矩形四边中点坐标。

            int ptX = 0;
            int ptY = 0;
            switch (linkPoint)
            {
                case ShapeLinkPoints.左:
                    ptX = Rect.X;
                    ptY = Rect.Y + Rect.Height / 2;
                    break;
                case ShapeLinkPoints.上:
                    ptX = Rect.X + Rect.Width / 2;
                    ptY = Rect.Y;
                    break;
                case ShapeLinkPoints.右:
                    ptX=Rect.X + Rect.Width;
                    ptY = Rect.Y + Rect.Height / 2;
                    break;
                case ShapeLinkPoints.下:
                default:
                    ptX = Rect.X + Rect.Width / 2;
                    ptY = Rect.Y + Rect.Height;
                    break;
            }
            return new Point(ptX, ptY);
        }

        //V3新增

        /// <summary>
        /// 获取连接点小矩形区域
        /// </summary>
        /// <param name="linkPoint"></param>
        /// <returns></returns>
        public virtual Rectangle GetLinkRect(ShapeLinkPoints linkPoint)
        {
            int ptX = 0;
            int ptY = 0;            
            int w = 10, h = 10, w_half = 5, h_half = 5;
            switch (linkPoint)
            {
                case ShapeLinkPoints.左:
                    ptX = Rect.X - w_half;
                    ptY = Rect.Y + Rect.Height / 2 - h_half;
                    break;
                case ShapeLinkPoints.上:
                    ptX = Rect.X + Rect.Width / 2 - w_half;
                    ptY = Rect.Y - h_half;
                    break;
                case ShapeLinkPoints.右:
                    ptX = Rect.X + Rect.Width - w_half;
                    ptY = Rect.Y + Rect.Height / 2 - h_half;
                    break;
                case ShapeLinkPoints.下:
                default:
                    ptX = Rect.X + Rect.Width / 2 - w_half;
                    ptY = Rect.Y + Rect.Height - h_half;
                    break;
            }
            return new Rectangle(ptX, ptY, w, h);
        }
        /// <summary>
        /// 获取所有连接点小矩形区域
        /// </summary>
        /// <returns></returns>
        public List<Rectangle> GetAllLinkRects()
        {
            return new List<Rectangle>()
            {
                GetLinkRect(ShapeLinkPoints.左),
                GetLinkRect(ShapeLinkPoints.上),
                GetLinkRect(ShapeLinkPoints.右),
                GetLinkRect(ShapeLinkPoints.下),
            };
        }

        /// <summary>
        /// 绘制所有连接点
        /// </summary>
        public virtual void DrawAllLinkRects(Graphics g)
        {
            var ls = GetAllLinkRects();
            g.FillRectangles(Brushes.Red/*默认以红色进行显示*/,ls.ToArray());
            g.DrawRectangles(Pens.White,ls.ToArray());
        }

        /// <summary>
        /// 绘制选中的连接点
        /// </summary>
        /// <param name="g"></param>
        /// <param name="linkPoint"></param>
        public virtual void DrawSelectedLinkRect(Graphics g, ShapeLinkPoints linkPoint)
        {
            //同上，默认以矩形方式实现
            var rect=GetLinkRect(linkPoint);
            g.FillRectangle(Brushes.Red ,rect);
            g.DrawRectangle(Pens.White, rect);
        }
                
        /// <summary>
        /// 绘制鼠标移动到连接点上时的聚焦状态
        /// </summary>
        /// <param name="g"></param>
        /// <param name="linkPoint"></param>
        public virtual void DrawFocusedLinkRect(Graphics g, ShapeLinkPoints linkPoint)
        {
            //默认以黄色矩形边框方式实现
            var rect=GetLinkRect(linkPoint);
            g.DrawRectangle(new Pen(Brushes.Yellow,2) ,rect);
        }
        /// <summary>
        /// 鼠标点是否在连接点区域内
        /// </summary>
        /// <param name="mousePt"></param>
        /// <returns></returns>
        public virtual bool IsHitLinkRect(Point mousePt)
        {
            var ls = GetAllLinkRects();
            var index = ls.FindIndex(a => a.Contains(mousePt));
            return index >= 0;
        }
        /// <summary>
        /// 鼠标点所处的连接点
        /// </summary>
        /// <param name="mousePt"></param>
        /// <returns></returns>
        public virtual ShapeLinkPoints GetHitLinkRect(Point mousePt)
        {
            var ls = GetAllLinkRects();
            var index = ls.FindIndex(a => a.Contains(mousePt));
            if (index < 0)
            {
                return ShapeLinkPoints.左;//没找到鼠标点所处的连接点，默认返回一个值
            }
            else
            {
                return (ShapeLinkPoints)index;
            }
        }

        //V5-PART2增加

        /// <summary>
        /// 鼠标点是否在连接点区域内
        /// </summary>
        /// <param name="mousePt"></param>
        /// <returns></returns>
        public virtual bool IsHitShape(Point mousePt)
        {
            //默认以矩形区域判断，各形状可自行实现
            return this.Rect.Contains(mousePt);
        }
    }
}
